﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SCRUM.Core.BusinessObjects;
using SCRUM.Core.DAO;
using System.Text;
using SCRUM.Core.MembershipProviders;

/// <summary>
/// Handles oprerations connected to task, like display, edit, create, delete
/// </summary>
public partial class TaskDetails : HierarchicalObjectDetails<Task, BLI>
{
    /// <summary>
    /// Logged in user
    /// </summary>
    private User loggedUser = DAOUser.GetLoggedUser();

    /// <summary>
    /// Taks object to handle
    /// </summary>
    public Task DetailedTask
    {
        get
        {
            return ViewState["DetailedTask"] as Task;
        }
        set
        {
            ViewState["DetailedTask"] = value;
            if (value != null)
            {
                this.oldAssignedUsers = value.AssignedUsers;
            }
        }
    }

    /// <summary>
    /// Assigned user for this task
    /// </summary>
    private IList<User> oldAssignedUsers
    {
        get
        {
            return ViewState["OldAssignedUsers"] as IList<User>;
        }
        set
        {
            ViewState["OldAssignedUsers"] = value;
        }
    }

    /// <summary>
    /// New users to assign for the task
    /// </summary>
    private IList<User> usersToAssign
    {
        get
        {
            return ViewState["UsersToAssign"] as IList<User>;
        }
        set
        {
            ViewState["UsersToAssign"] = value;
        }
    }

    /// <summary>
    /// Loads the extended inputs.
    /// </summary>
    /// <returns></returns>
    protected override IList<ScrumInput> LoadExtendedInputs()
    {
        return this.LoadExtendedInputsFrom(PanelItemDetails);
    }

    /// <summary>
    /// Loads the available superior items(=BLIs).
    /// </summary>
    protected override void LoadAvailableSuperiorItems()
    {
        AvailableSuperiorItems = DAOBli.GetAllBlis();
    }

    /// <summary>
    /// Displays all fields of the selected item into textboxes in form.
    /// </summary>
    public override void DisplayItem(Task task)
    {
        this.Visible = true;

        Bli.DataSource = AvailableSuperiorItems;
        Bli.DataBind();

        bool exists = task != null;

        this.Header.LastChange =            exists ? task.LastChange    : DateTime.MinValue;
        this.Name.Text =                    exists ? task.Name          : "";
        this.Description.Text =             exists ? task.Description   : "";
        this.Priority.SelectedPriority =    exists ? task.Priority      : 2;
        this.States.SelectedState =         exists ? task.State         : State.DefaultState(State.StateTypes.Task);
        this.ProgressBar.Progress =         exists ? task.Progress      : 0;
        this.Estimation.Value =             exists ? task.Estimation    : 0;
        int superiorItemID =                exists ? task.SuperiorItemID: this.SuperiorItemID;
        if (superiorItemID != -1)
        {
            this.Bli.SelectedValue = superiorItemID.ToString();
        }
        
        // enabled
        this.States.Enabled = exists;
        this.Bli.Enabled = exists;

        // visible
        this.ProgressBar.Visible = exists;

        // readonly

        if (exists)
        {
            DropDownListUsers.Visible = true;
            ListViewAssociatedUsers.DataSource = task.AssignedUsers;
            ListViewAssociatedUsers.DataBind();
            BindUsersDropDownList(task.ID);
        }
        else
        {
            //ListViewAssociatedUsers.DataSource = null;
            //ListViewAssociatedUsers.DataBind();
            //ListViewAssociatedUsers.Visible = false;
            BindUsersDropDownList(-1);
            DropDownListUsers.Visible = false;
        }
    }

    /// <summary>
    /// Binds the DropDownList.
    /// </summary>
    protected void BindUsersDropDownList(int taskID)
    {
        if (this.DetailedTask == null)//usersToAssign == null)
        {
            this.usersToAssign = DAOUser.GetUsersExceptTaskUsers(taskID);
        }
        DropDownListUsers.DataSource = this.usersToAssign;
        DropDownListUsers.DataBind();
    }

    /// <summary>
    /// Manages the user.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Web.UI.WebControls.CommandEventArgs"/> instance containing the event data.</param>
    protected void ManageUser(object sender, CommandEventArgs e)
    {
        Task task = this.DetailedTask;

        switch ((string)e.CommandName)
        {
            case "Remove":
                User oldUser = DAOUser.GetByLogin((string)e.CommandArgument);
                this.DetailedTask.AssignedUsers.Remove(oldUser);
                this.usersToAssign.Add(oldUser);

                break;
            case "Add":
                User newUser = DAOUser.GetByLogin(this.DropDownListUsers.SelectedValue);
                this.DetailedTask.AssignedUsers.Add(newUser);
                this.usersToAssign.Remove(newUser);
                break;
            default:
                break;
        }

        ListViewAssociatedUsers.DataSource = this.DetailedTask.AssignedUsers;
        ListViewAssociatedUsers.DataBind();
        BindUsersDropDownList(this.DetailedTask.ID);
        this.Visible = true;
    }

    /// <summary>
    /// Occurs on itemdatabound of the listview.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Web.UI.WebControls.ListViewItemEventArgs"/> instance containing the event data.</param>
    protected void ListViewItemDataBound(object sender, ListViewItemEventArgs e)
    {
        if (e.Item.ItemType != ListViewItemType.DataItem)
        {
            return;
        }
        ImageButton imageDelete = (ImageButton)e.Item.FindControl("ImageDelete");
        if (((e.Item as ListViewDataItem).DataItem as User).Equals(this.loggedUser))
        {
            imageDelete.Visible = true;
        }
    }

    /// <summary>
    /// Creates new task
    /// </summary>
    /// <returns>Created Task</returns>
    public override Task CreateItem()
    {
        int bliID = Int32.Parse(Bli.SelectedValue);
        Task tsk = new Task(
            0, 
            Name.Text, 
            Description.Text,
            Estimation.Value,
            States.SelectedState.ID,
            ProgressBar.Progress,
            Priority.SelectedPriority,
            DateTime.Now,
            bliID
        );
        Task newTsk = DAOTask.CreateTask(tsk, bliID);
        return newTsk;
    }

    /// <summary>
    /// Edits Task according to data in Task detail panel
    /// </summary>
    /// <param name="oldTaskID">Id of Task to update</param>
    public override Task EditItem(int oldTaskID)
    {
        int bliID = Int32.Parse(Bli.SelectedValue);
        Task task = new Task(
            oldTaskID, 
            Name.Text,
            Description.Text,
            System.Convert.ToInt32(Estimation.Text),
            States.SelectedState.ID,
            ProgressBar.Progress,
            Priority.SelectedPriority,
            DateTime.Now,
            bliID
        );
        DAOTask.UpdateTask(task, bliID);
        this.Visible = false;
        task.BacklogItem.ID = bliID;

        // Update assigned users to the task
        foreach (User user in this.UserExcept(this.oldAssignedUsers, this.DetailedTask.AssignedUsers))
        {
            DAOTask.RemoveAssociatedUser(task, user.ID);
        }
        foreach (User user in this.UserExcept(this.DetailedTask.AssignedUsers, this.oldAssignedUsers))
        {
            DAOTask.AddAssociatedUser(task, user.ID);
        }

        DisplayItem(task);
        return task;
    }

    /// <summary>
    /// Makes difference list of two lists.
    /// </summary>
    /// <param name="users1">The users1.</param>
    /// <param name="users2">The users2.</param>
    /// <returns></returns>
    private IList<User> UserExcept(IList<User> users1, IList<User> users2)
    {
        IList<User> newUsers = new List<User>();
        foreach (User user in users1)
        {
            if (!users2.Contains(user, new User()))
            {
                newUsers.Add(user);
            }
        }
        return newUsers;
    }

    /// <summary>
    /// Deletes Task
    /// </summary>
    /// <param name="task">Task to delete</param>
    public override void DeleteItem(Task tsk)
    {
        DAOTask.DeleteTask(tsk.ID);
        this.Visible = false;
    }

    /// <summary>
    /// Validates the input.
    /// </summary>
    /// <returns>REsult of validation</returns>
    public override bool ValidateInput()
    {
        throw new NotImplementedException();
        return true;
    }

    protected override Panel panelWithControls { get { return this.PanelItemDetails; } }
}